
#include <string.h>
#include "fun.h"
#include "Debug.h"
#include "BSP.h"
//	#include "Driver.h"
#include "BSP_Timer.h"
#include "Timer.h"
#include <log.h>
#include "FreeRTOS.h"
#include "atomic.h"
#include "Task.h"
#include "Timers.h"
#include "version.h"
#include "task_config.h"
#include "semphr.h"

#include "SimpleTag.h"

#include "id_card.h"
#include "HIDProx.h"

void rfid_itf_clr_tag(uint8_t tag);
int id_card_get(uint8_t uid[5]);
uint8_t rfid_itf_support(void);


#define LF_PRESENT_COUNT		50

typedef enum {
	LF_S_IDLE,		//空闲
	LF_S_START,		//启动
	LF_S_POLLING,	//寻卡中
//	LF_S_PRESENT,	//卡在场
	LF_S_WAITTING,	//等待读卡
	LF_S_OK,		//读卡成功
	LF_S_CLOSE,		
}LF_State_T;

static volatile LF_State_T readerLFState;
//	static volatile uint32_t readerLFTick;
static SimpleTag_T lfTag;
static int8_t lfPresentCount;
static int8_t lfReadTime;
static int8_t lfReadCount;
static TimerHandle_t lfTimer;
static SemaphoreHandle_t hSemLF = NULL;

static uint8_t id_uid_buf[5];

static void reader_id_clear_uid(void){
	memset(id_uid_buf, 0, sizeof(id_uid_buf));
}

static int reader_id_is_invalid_uid(uint8_t* uid){
	static const uint8_t invalid_uid[5] = {0x00};
	if(memcmp(invalid_uid, uid, 5) == 0){
		return 1;
	}
	return 0;
}

static int reader_id_check_update(uint8_t* uid){
	if(memcmp(uid, id_uid_buf, 5)){
		memcpy(id_uid_buf, uid, 5);
		return 0;
	}
	else{
		return 1;
	}
}

static int reader_id_read(SimpleTag_T* tag){
	uint8_t uid[5];
	int ret = id_card_get(uid);
	if(ret){
		return ret;
	}
	if(reader_id_is_invalid_uid(uid)){
		return -1;
	}
	if(!reader_id_check_update(uid)){
		return 1;
	}
	uint8_t uid_len = 5;
	uint8_t uid_bit = uid_len * 8;
	SimpleTag_Set(tag, LFTAG_EM4102, uid_bit, uid_len, uid);
	reader_id_clear_uid();
	
	return ret;
}

static int Reader_LF_DoRead(SimpleTag_T* tag){
	int ret = -1;
	uint8_t support = rfid_itf_support();
	
	if(support & RFID_ITF_TAG_HID){
		HidProxTag_T info;
		info.type = 0xFF;
		//HID Prox
		ret = HIDProx_Read(&info);
		if(ret == 0){
			uint8_t uid_len = (info.type + 7) / 8;
			uint8_t uid_bit = info.type;
			SimpleTag_Set(tag, LFTAG_HIDPROX, uid_bit, uid_len, info.uid);
		}
		
		if(ret >= 0){
			return ret;
		}
	}
	
	if(support & RFID_ITF_TAG_ID){
		//EM4200
		ret = reader_id_read(tag);
	}
	
	return ret;
}

static void Reader_LF_Tick( TimerHandle_t xTimer ){
	if(lfReadTime > 0){
		lfReadTime--;
	}
	if(lfPresentCount > 0){
		lfPresentCount--;
	}
}


void Reader_LF_Init(void){
	lfPresentCount = -1;
	lfReadTime = -1;

	readerLFState = LF_S_IDLE;
	hSemLF = xSemaphoreCreateBinary();
	xSemaphoreTake( hSemLF, ( TickType_t ) 0 );
	lfTimer = xTimerCreate("lf", pdMS_TO_TICKS(10), pdTRUE, NULL, Reader_LF_Tick);
	xTimerStart(lfTimer, portMAX_DELAY);
	HIDProx_Init();
}

void Reader_LF_RfOff(void){
	lfReadTime = 0;
	lfReadCount = 0;
	lfPresentCount = -1;
	readerLFState = LF_S_CLOSE;
}

int Reader_LF_Read(uint32_t flag, SimpleTag_T* tag){
	uint8_t count;
	rfid_itf_write_flag(flag);
	if(lfReadCount > 0 && lfPresentCount > 0){
		lfReadCount--;
		*tag = lfTag;
		LOG_TIME();
		LOGI("id", "Continue TAG");
		vTaskDelay(10);
		return 0;
	}
	
	if(readerLFState == LF_S_OK){

		count = 7;
		while(count > 0){
			count--;
			vTaskDelay(10);
			if(readerLFState != LF_S_OK){
				LOG_TIME();
				LOGE("id", "TAG Leave");
				return -1;
			}
		}
		*tag = lfTag;
		LOG_TIME();
		LOGI("id", "Keep TAG");
		return 0;
	}

	if(readerLFState == LF_S_IDLE || readerLFState == LF_S_CLOSE){
		lfReadTime = 25;
		readerLFState = LF_S_START;
		xSemaphoreGive(hSemLF);
	}
	//HID Prox 64bit,需要更长的读卡时间，因此count 加大到20
	count = 20;
	//等待读卡完成
	while (count > 0){
		count--;
		vTaskDelay(10);
		switch(readerLFState){
		case LF_S_OK:{
			//返回卡号
			if(lfReadCount > 0){
				lfReadCount--;
			}
			*tag = lfTag;
			LOG_TIME();
			LOGI("id", "Get TAG");
			return 0;
		}

		case LF_S_IDLE:{
			//读卡结束
			LOG_TIME();
			LOGE("id", "LF_S_IDLE");
			return -2;
		}
		default: break;
		}
	}
	//未读到卡
	LOG_TIME();
	LOGE("id", "Timeout");
	return -1;
}


int Reader_LF_Service(void){
	SimpleTag_T tag;
	int ret = -1;

	switch(readerLFState){
	case LF_S_IDLE:{
		xSemaphoreTake( hSemLF, 100);
	}
	break;
	case LF_S_START:{
		HIDProx_Reset();
		id_card_reset();
		reader_id_clear_uid();
		BSP_RFID_Enable();
		lfReadCount = 0;
		lfReadTime = 25;
		readerLFState = LF_S_POLLING;
		LOGI("id", "LF_S_POLLING(%d)", __LINE__);
	}
	break;
	case LF_S_POLLING:{
		ret = Reader_LF_DoRead(&tag);
		if(!ret){
			break;
		}
	}
	break;
	case LF_S_CLOSE:{
		BSP_RFID_Disable();
		ATOMIC_ENTER_CRITICAL();
		{
			rfid_itf_clr_tag(RFID_ITF_TAG_ID | RFID_ITF_TAG_HID);
		}
		ATOMIC_EXIT_CRITICAL();
		readerLFState = LF_S_IDLE;
		LOGI("id", "LF_S_IDLE(%d)", __LINE__);
	}
	break;
	default:{
		ret = Reader_LF_DoRead(&tag);
	}
	break;
	}

	if(!ret){
		lfTag = tag;
		lfReadTime = 20;
		lfReadCount = 2;
		readerLFState = LF_S_OK;
		LOG_TIME();
		LOGI("id", "LF_S_OK(%d)", __LINE__);
		lfPresentCount = LF_PRESENT_COUNT;
	}
	else
	if(ret > 0 && lfReadTime > 0){
		if(lfPresentCount > 0){
			//有卡，但是读卡错误
			lfReadTime = 20;
			lfReadCount = 2;
		}
	}
	
	if(lfReadTime == 0){
		lfReadTime = -1;
		lfReadCount = 0;
		readerLFState = LF_S_CLOSE;
		memset(&lfTag, 0, sizeof(lfTag));
		LOGI("id", "LF_S_CLOSE(%d)", __LINE__);
	}
	
	return 0;
}


